﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.Revit;

namespace HYFloorPipeModule
{
	public class FloorPipeTools
	{
		public FloorPipeTools(Autodesk.Revit.DB.Document Doc)
		{
			this.doc = Doc;
		}

		public FloorPipeTools(UIApplication uiApp)
		{
			this.uiApplication = uiApp;
			this.doc = uiApp.ActiveUIDocument.Document;
		}

		public FloorPipeTools()
		{
		}

		public Reference PickUpRoomOrSpace(ref Element room, Autodesk.Revit.DB.Document document, Selection selection, ref Document docment, bool beLink = false)
		{
			if (beLink)
			{
				Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)5, "请选择链接模型内的房间或空间……");
				Document linkDocument = (document.GetElement(reference) as RevitLinkInstance).GetLinkDocument();
				docment = linkDocument;
				Element elementById = linkDocument.GetElementById(reference.LinkedElementId);
				if (!(elementById is Room) && !(elementById is Space))
				{
					return null;
				}
				room = elementById;
			}
			else
			{
				RoomAndSpaceSelectionFilter roomAndSpaceSelectionFilter = new RoomAndSpaceSelectionFilter();
				Reference reference2 = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, roomAndSpaceSelectionFilter, "请选择当前模型中的房间或空间……");
				room = document.GetElementByRef(reference2);
				docment = this.doc;
			}
			Reference reference3 = null;
			List<Element> doorsInSpaceOrRoom = YJKRevitTools.GetDoorsInSpaceOrRoom(room);
			int count = doorsInSpaceOrRoom.Count;
			if (count != 0 && count != 1)
			{
				if (beLink)
				{
					reference3 = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)5, "请选定选定房间的任一个门：");
					Document linkDocument2 = (document.GetElement(reference3) as RevitLinkInstance).GetLinkDocument();
					Element elementById2 = linkDocument2.GetElementById(reference3.LinkedElementId);
					while (!this.IsElementInSet(elementById2, doorsInSpaceOrRoom))
					{
						YJKMessageBox.Information("请选择当前房间的门！");
						reference3 = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)5, "请选定选定房间的任一个门：");
						elementById2 = linkDocument2.GetElementById(reference3.LinkedElementId);
					}
				}
				else
				{
					reference3 = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, new YJKDoorFilter(), "请选定选定房间的任一个门：");
					while (!this.IsElementInSet(document.GetElement(reference3), doorsInSpaceOrRoom))
					{
						YJKMessageBox.Information("请选择当前房间的门！");
						reference3 = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, new YJKDoorFilter(), "请选定选定房间的任一个门：");
					}
				}
			}
			return reference3;
		}

		private bool IsElementInSet(Element door, List<Element> doors)
		{
			return (from d in doors
			select d.Id).ToList<ElementId>().Contains(door.Id);
		}

		private bool DoorLayInRoom(Element room, FamilyInstance fi)
		{
			return (fi.Room != null && fi.Room.Id.Equals(room.Id)) || (fi.Space != null && fi.Space.Id.Equals(room.Id));
		}

		public List<XYZ> DealRectPoints(XYZ pt1, XYZ pt2, XYZ pt3, Selection selection)
		{
			Line line = Line.CreateBound(pt1, pt2);
			line.MakeUnbound();
			pt2 = line.Project(pt3).XYZPoint;
			XYZ xyzpoint = Line.CreateUnbound(pt3, (pt2 - pt1).Normalize()).Project(pt1).XYZPoint;
			List<XYZ> points = new List<XYZ>
			{
				pt1,
				pt2,
				pt3,
				xyzpoint
			};
			XYZ facingDir = null;
			XYZ ptDoor = this.SelectDirPoint(points, selection, out facingDir);
			return this.ReOrderPointByDoorPos(points, ptDoor, facingDir);
		}

		public List<MixPair> DealYxPoints(List<XYZ> points, Selection selection)
		{
			XYZ xyz = null;
			XYZ xyz2 = this.SelectDirPoint(points, selection, out xyz);
			List<MixPair> list = new List<MixPair>();
			for (int i = 1; i < points.Count; i++)
			{
				list.Add(new MixPair(points[i - 1], points[i], false));
				if (i == points.Count - 1)
				{
					list.Add(new MixPair(points[i], points[0], false));
				}
			}
			if (xyz2 != null)
			{
				return this.ReOrderBounding(list, xyz2, 0.0);
			}
			return list;
		}

		private XYZ SelectDirPoint(List<XYZ> points, Selection selection, out XYZ dir)
		{
			List<Element> list = this.CreatModelLine(points);
			try
			{
				this.doc.Regenerate();
				Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, new HYModelLineFilter(), "请选择门的位置：");
				while (!this.IsElementInSet(this.doc.GetElement(reference), list))
				{
					YJKMessageBox.Information("请在当前的绘制边界上选门的位置：");
					reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, new HYModelLineFilter(), "请选择门的位置：");
				}
				dir = (((this.doc.GetElement(reference) as ModelLine).Location as LocationCurve).Curve as Line).Direction.CrossProduct(new XYZ(0.0, 0.0, 1.0));
				XYZ globalPoint = reference.GlobalPoint;
				this.doc.Delete((from line in list
				select line.Id).ToList<ElementId>());
				return globalPoint;
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				dir = null;
				this.doc.Delete((from line in list
				select line.Id).ToList<ElementId>());
			}
			return null;
		}

		public Dictionary<XYZ, XYZ> GetLInkRoomDoorLocation(UIApplication uiApp, Element elem)
		{
			Dictionary<XYZ, XYZ> dictionary = new Dictionary<XYZ, XYZ>();
			FilteredElementCollector elementsOfType = YJKElementFilter.GetElementsOfType(this.doc, typeof(Instance), BuiltInCategory.OST_RvtLinks);
			IList<string> linkFilePaths = YJKRevitTools.GetLinkFilePaths(this.doc);
			foreach (Element element in elementsOfType)
			{
				Instance instance = element as Instance;
				if (instance != null)
				{
					Transform totalTransform = instance.GetTotalTransform();
					string value = instance.Name.Substring(0, instance.Name.IndexOf(".rvt"));
					string text = "";
					foreach (string text2 in linkFilePaths)
					{
						if (text2.Contains(value))
						{
							text = text2;
						}
					}
					if (File.Exists(text))
					{
						FilteredElementCollector filteredElementCollector = new FilteredElementCollector(uiApp.Application.OpenDocumentFile(text));
						filteredElementCollector.OfCategory(BuiltInCategory.OST_Rooms);
						foreach (Element element2 in filteredElementCollector)
						{
							Room room = element2 as Room;
							if (room.Location != null && ((room.Location as LocationPoint).Point + totalTransform.Origin).DistanceTo((elem.Location as LocationPoint).Point) < 0.001)
							{
								List<Element> doorsInSpaceOrRoom = YJKRevitTools.GetDoorsInSpaceOrRoom(room);
								if (doorsInSpaceOrRoom.Count == 1)
								{
									dictionary.Add((doorsInSpaceOrRoom[0].Location as LocationPoint).Point, (doorsInSpaceOrRoom[0] as FamilyInstance).FacingOrientation);
								}
							}
						}
					}
				}
			}
			if (dictionary.Count != 0)
			{
				return dictionary;
			}
			return null;
		}

		public List<List<XYZ>> GetRoomInfoXyzs(Element room, Reference refer, Selection sel, int num = 1, Autodesk.Revit.DB.Document docment = null)
		{
			List<List<XYZ>> list = new List<List<XYZ>>();
			List<XYZ> list2 = this.MergeBoundings(YJKRevitTools.GetSpaceOrRoomBoundaryCurve(room));
			if (list2 == null || list2.Count != 4)
			{
				return null;
			}
			List<XYZ> list3;
			if (refer == null)
			{
				Dictionary<XYZ, XYZ> dictionary = this.GetDoorLayPointInRectRoom(room);
				dictionary = (dictionary ?? this.GetLInkRoomDoorLocation(this.uiApplication, room));
				XYZ xyz = (dictionary != null) ? dictionary.Keys.ElementAt(0) : null;
				if (room.Document.IsLinked)
				{
					LinkedDocument linkedDocument = this.doc.GetLinkedDocument(room.Id);
					for (int i = 0; i < list2.Count; i++)
					{
						list2[i] = linkedDocument.GetPointInLinkDocument(list2[i]);
					}
				}
				list3 = ((xyz != null) ? this.ReOrderPointByDoorPos(list2, xyz, dictionary[xyz]) : this.DealRectPoints(list2[0], list2[1], list2[2], sel));
			}
			else
			{
				Element element;
				if (docment != null)
				{
					element = docment.GetElementById(refer.LinkedElementId);
				}
				else
				{
					element = this.doc.GetElement(refer);
				}
				XYZ ptDoor = refer.GlobalPoint;
				XYZ facingDir;
				if (element is Wall)
				{
					Curve curve = (element.Location as LocationCurve).Curve;
					ptDoor = curve.Project(refer.GlobalPoint).XYZPoint;
					facingDir = (curve as Line).Direction.CrossProduct(new XYZ(0.0, 0.0, 1.0));
				}
				else
				{
					ptDoor = (element.Location as LocationPoint).Point;
					facingDir = (element as FamilyInstance).FacingOrientation;
				}
				list3 = this.ReOrderPointByDoorPos(list2, ptDoor, facingDir);
			}
			if (num > 1)
			{
				return this.SplitRectangl(list3, num);
			}
			list.Add(list3);
			return list;
		}

		private List<XYZ> MergeBoundings(List<Curve> roomBounds)
		{
			List<XYZ> list = new List<XYZ>();
			for (int i = 0; i < roomBounds.Count; i++)
			{
				int index = i;
				int index2 = i + 1;
				if (i == roomBounds.Count - 1)
				{
					index2 = 0;
				}
				if (roomBounds[index] is Line && roomBounds[index2] is Line)
				{
					XYZ direction = (roomBounds[index] as Line).Direction;
					XYZ direction2 = (roomBounds[index2] as Line).Direction;
					XYZ endPoint = roomBounds[index].GetEndPoint(1);
					XYZ endPoint2 = roomBounds[index2].GetEndPoint(0);
					if (!endPoint.IsAlmostEqualTo(endPoint2) || !direction.IsAlmostEqualTo(direction2))
					{
						list.Add(endPoint);
						if (Math.Abs(Math.PI*.5 - direction.AngleTo(direction2)) > 1E-05)
						{
							return null;
						}
					}
				}
			}
			return list;
		}

		public List<List<XYZ>> SplitRectangl(List<XYZ> points, int nNum)
		{
			List<List<XYZ>> list = new List<List<XYZ>>();
			double num = Math.Max(points[0].DistanceTo(points[1]), points[1].DistanceTo(points[2]));
			double num2 = num / (double)nNum;
			if (points[0].DistanceTo(points[1]) == num)
			{
				XYZ xyz = (points[1] - points[0]).Normalize();
				for (int i = 0; i < nNum - 1; i++)
				{
					List<XYZ> list2 = new List<XYZ>();
					XYZ xyz2 = points[0] + xyz * num2;
					XYZ xyz3 = points[3] + xyz * num2;
					list2.AddRange(new XYZ[]
					{
						points[0],
						xyz2,
						xyz3,
						points[3]
					});
					list.Add(list2);
					points[0] = new XYZ(xyz2.X, xyz2.Y, xyz2.Z);
					points[3] = new XYZ(xyz3.X, xyz3.Y, xyz3.Z);
				}
				list.Add(points);
			}
			else
			{
				XYZ xyz4 = (points[2] - points[1]).Normalize();
				for (int j = 0; j < nNum - 1; j++)
				{
					List<XYZ> list3 = new List<XYZ>();
					XYZ xyz5 = points[1] + xyz4 * num2;
					XYZ xyz6 = points[0] + xyz4 * num2;
					list3.AddRange(new XYZ[]
					{
						points[0],
						points[1],
						xyz5,
						xyz6
					});
					list.Add(list3);
					points[1] = new XYZ(xyz5.X, xyz5.Y, xyz5.Z);
					points[0] = new XYZ(xyz6.X, xyz6.Y, xyz6.Z);
				}
				list.Add(new List<XYZ>(new XYZ[]
				{
					points[0],
					points[1],
					points[2],
					points[3]
				}));
			}
			return list;
		}

		private List<XYZ> ReOrderPointByDoorPos(List<XYZ> points, XYZ ptDoor, XYZ facingDir)
		{
			if (ptDoor == null)
			{
				return points;
			}
			List<double> list = points.Select(new Func<XYZ, double>(ptDoor.DistanceTo)).ToList<double>();
			list.Sort();
			int num = 0;
			for (int i = 0; i < points.Count; i++)
			{
				if (points[i].DistanceTo(ptDoor) == list[0])
				{
					num = i;
				}
			}
			List<XYZ> list2 = new List<XYZ>();
			for (int j = num; j < points.Count; j++)
			{
				list2.Add(points[j]);
				if (j == points.Count - 1 && list2.Count < points.Count)
				{
					j = -1;
				}
				if (list2.Count == points.Count)
				{
					break;
				}
			}
			XYZ xyz = (list2[2] - list2[1]).Normalize();
			if (xyz.IsAlmostEqualTo(facingDir) || xyz.IsAlmostEqualTo(-facingDir))
			{
				XYZ value = list2[3];
				list2[3] = list2[1];
				list2[1] = value;
			}
			return list2;
		}

		public Dictionary<XYZ, XYZ> GetDoorLayPointInRectRoom(Element room)
		{
			Dictionary<XYZ, XYZ> dictionary = new Dictionary<XYZ, XYZ>();
			foreach (Element element in YJKRevitTools.GetDoorsInSpaceOrRoom(room))
			{
				XYZ point = (element.Location as LocationPoint).Point;
				XYZ facingOrientation = (element as FamilyInstance).FacingOrientation;
				dictionary.Add(point, facingOrientation);
			}
			if (dictionary.Count == 0)
			{
				return null;
			}
			return dictionary;
		}

		public List<MixPair> GetRoomBoundingInfo(Element room, Selection selection, Reference refer = null, Autodesk.Revit.DB.Document linkdocment = null)
		{
			List<MixPair> list = this.MergeYXBoundings(YJKRevitTools.GetSpaceOrRoomBoundaryCurve(room));
			if (refer != null)
			{
				Element element;
				if (linkdocment != null)
				{
					element = linkdocment.GetElementById(refer.LinkedElementId);
				}
				else
				{
					element = this.doc.GetElement(refer);
				}
				if (element is Wall)
				{
					XYZ xyzpoint = (element.Location as LocationCurve).Curve.Project(refer.GlobalPoint).XYZPoint;
					return this.ReOrderBounding(list, xyzpoint, (element as Wall).Width);
				}
				XYZ point = (element.Location as LocationPoint).Point;
				return this.ReOrderBounding(list, point, ((element as FamilyInstance).Host as Wall).Width);
			}
			else
			{
				Dictionary<XYZ, double> doorLayPointInYxRoom = this.GetDoorLayPointInYxRoom(room);
				Dictionary<XYZ, XYZ> linkRoomDoorLocation = this.GetLInkRoomDoorLocation(this.uiApplication, room);
				if (doorLayPointInYxRoom != null)
				{
					XYZ xyz = doorLayPointInYxRoom.Keys.ElementAt(0);
					return this.ReOrderBounding(list, xyz, doorLayPointInYxRoom[xyz]);
				}
				if (linkRoomDoorLocation != null)
				{
					XYZ xyz2 = linkRoomDoorLocation.Keys.ElementAt(0);
					return this.ReOrderBounding(list, xyz2, doorLayPointInYxRoom[xyz2]);
				}
				List<XYZ> points = (from mp in list
				select mp.Start).ToList<XYZ>();
				XYZ xyz3 = null;
				XYZ xyz4 = this.SelectDirPoint(points, selection, out xyz3);
				if (xyz4 != null)
				{
					return this.ReOrderBounding(list, xyz4, 0.0);
				}
				return list;
			}
		}

		private List<MixPair> MergeYXBoundings(List<Curve> roomBounds)
		{
			List<MixPair> list = new List<MixPair>();
			XYZ xyz = null;
			bool flag = false;
			for (int i = 0; i < roomBounds.Count; i++)
			{
				int index = i;
				int num = i + 1;
				if (i == roomBounds.Count - 1)
				{
					num = 0;
				}
				if (!flag)
				{
					xyz = roomBounds[index].GetEndPoint(0);
				}
				if (roomBounds[index] is Line && roomBounds[num] is Line)
				{
					XYZ direction = (roomBounds[index] as Line).Direction;
					XYZ direction2 = (roomBounds[num] as Line).Direction;
					XYZ endPoint = roomBounds[index].GetEndPoint(1);
					XYZ endPoint2 = roomBounds[num].GetEndPoint(0);
					if (endPoint.IsAlmostEqualTo(endPoint2) && direction.IsAlmostEqualTo(direction2))
					{
						flag = true;
						if (num == 0)
						{
							list[0].Start = xyz;
						}
					}
					else
					{
						XYZ endPoint3 = roomBounds[index].GetEndPoint(1);
						MixPair item = new MixPair(xyz, endPoint3, false);
						list.Add(item);
						flag = false;
					}
				}
				else if (roomBounds[index] is Arc && roomBounds[num] is Arc)
				{
					XYZ endPoint4 = roomBounds[index].GetEndPoint(1);
					XYZ endPoint5 = roomBounds[num].GetEndPoint(0);
					XYZ center = (roomBounds[index] as Arc).Center;
					XYZ center2 = (roomBounds[num] as Arc).Center;
					if (center.IsAlmostEqualTo(center2) && endPoint4.IsAlmostEqualTo(endPoint5))
					{
						flag = true;
						if (num == 0)
						{
							list[0].Start = xyz;
						}
					}
					else
					{
						XYZ endPoint6 = roomBounds[index].GetEndPoint(0);
						XYZ endPoint7 = roomBounds[index].GetEndPoint(1);
						MixPair item2 = new MixPair(xyz, endPoint6, endPoint7, false);
						list.Add(item2);
						flag = false;
					}
				}
				else
				{
					MixPair item3;
					if (roomBounds[index] is Line)
					{
						XYZ endPoint8 = roomBounds[index].GetEndPoint(1);
						item3 = new MixPair(xyz, endPoint8, false);
					}
					else
					{
						XYZ xyz2 = roomBounds[index].GetEndPoint(0);
						XYZ endPoint9 = roomBounds[index].GetEndPoint(1);
						xyz2 = roomBounds[index].Project(0.5 * (xyz2 + endPoint9)).XYZPoint;
						item3 = new MixPair(xyz, xyz2, endPoint9, false);
					}
					list.Add(item3);
					flag = false;
				}
			}
			return list;
		}

		public Dictionary<XYZ, double> GetDoorLayPointInYxRoom(Element room)
		{
			Dictionary<XYZ, double> dictionary = new Dictionary<XYZ, double>();
			foreach (Element element in YJKRevitTools.GetDoorsInSpaceOrRoom(room))
			{
				XYZ point = (element.Location as LocationPoint).Point;
				double width = ((element as FamilyInstance).Host as Wall).Width;
				dictionary.Add(point, width);
			}
			if (dictionary.Count == 0)
			{
				return null;
			}
			return dictionary;
		}

		private List<MixPair> ReOrderBounding(List<MixPair> mixPairs, XYZ ptDoor, double wallWidth)
		{
			List<MixPair> list = new List<MixPair>();
			int num = 0;
			bool flag = false;
			int i = 0;
			while (i < mixPairs.Count)
			{
				XYZ xyzpoint = mixPairs[i].CreateCurve().Project(ptDoor).XYZPoint;
				if (Math.Abs(ptDoor.DistanceTo(xyzpoint) - wallWidth * 0.5) < 0.001)
				{
					num = i;
					if (ptDoor.DistanceTo(mixPairs[i].Start) > ptDoor.DistanceTo(mixPairs[i].End))
					{
						flag = true;
						break;
					}
					break;
				}
				else
				{
					i++;
				}
			}
			for (int j = num; j < mixPairs.Count; j++)
			{
				list.Add(new MixPair(mixPairs[j]));
				if (j == mixPairs.Count - 1 && list.Count < mixPairs.Count)
				{
					j = -1;
				}
				if (list.Count == mixPairs.Count)
				{
					break;
				}
			}
			if (flag)
			{
				this.MixPairsReverse(ref list);
			}
			list.Reverse();
			list.ForEach(delegate(MixPair mp)
			{
				mp.DoExchange();
			});
			return list;
		}

		private void MixPairsReverse(ref List<MixPair> mps)
		{
			mps.Reverse();
			foreach (MixPair mixPair in mps)
			{
				mixPair.DoExchange();
			}
			MixPair item = new MixPair(mps.Last<MixPair>());
			mps.Remove(mps.Last<MixPair>());
			mps.Insert(0, item);
		}

		public IDictionary<string, string> GetDicFromFloorPipeGroupData(FloorPipeGroupData floorPipeGroupData)
		{
			IDictionary<string, string> dictionary = new Dictionary<string, string>();
			if (floorPipeGroupData.drawFloorPipeData != null)
			{
				foreach (PropertyInfo propertyInfo in floorPipeGroupData.drawFloorPipeData.GetType().GetProperties())
				{
					if (propertyInfo.Name == "InType" || propertyInfo.Name == "OutType")
					{
						dictionary.Add(propertyInfo.Name, (propertyInfo.GetValue(floorPipeGroupData.drawFloorPipeData) as GraphicsStyle).Name);
					}
					else if (propertyInfo.Name == "PipeStyle")
					{
						dictionary.Add(propertyInfo.Name, ((int)propertyInfo.GetValue(floorPipeGroupData.drawFloorPipeData)).ToString());
					}
					else
					{
						dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(floorPipeGroupData.drawFloorPipeData).ToString());
					}
				}
				dictionary.Add("IsRect", true.ToString());
			}
			else
			{
				foreach (PropertyInfo propertyInfo2 in floorPipeGroupData.drawYxFloorPipeData.GetType().GetProperties())
				{
					if (propertyInfo2.Name == "InType" || propertyInfo2.Name == "OutType")
					{
						dictionary.Add(propertyInfo2.Name, (propertyInfo2.GetValue(floorPipeGroupData.drawYxFloorPipeData) as GraphicsStyle).Name);
					}
					else
					{
						dictionary.Add(propertyInfo2.Name, propertyInfo2.GetValue(floorPipeGroupData.drawYxFloorPipeData).ToString());
					}
				}
				dictionary.Add("IsRect", false.ToString());
			}
			dictionary.Add("PipeLength", floorPipeGroupData.PipesLength.ToString());
			dictionary.Add("PipeInId", floorPipeGroupData.PipeInId.IntegerValue.ToString());
			dictionary.Add("PipeLastId", (floorPipeGroupData.PipeLastId == null) ? "-1" : floorPipeGroupData.PipeLastId.IntegerValue.ToString());
			return dictionary;
		}

		public FloorPipeGroupData GetFloorPipeDataFromDic(IDictionary<string, string> dic)
		{
			FloorPipeGroupData floorPipeGroupData = new FloorPipeGroupData();
			if (bool.Parse(dic["IsRect"]))
			{
				if (floorPipeGroupData.drawFloorPipeData == null)
				{
					floorPipeGroupData.drawFloorPipeData = new DrawFloorPipeData();
				}
				foreach (PropertyInfo propertyInfo in floorPipeGroupData.drawFloorPipeData.GetType().GetProperties())
				{
					if (propertyInfo.Name == "InType" || propertyInfo.Name == "OutType")
					{
						propertyInfo.SetValue(floorPipeGroupData.drawFloorPipeData, this.GetGraphicsStyleByName(dic[propertyInfo.Name]));
					}
					else if (propertyInfo.Name == "PipeStyle")
					{
						propertyInfo.SetValue(floorPipeGroupData.drawFloorPipeData, (FloorPipeStyle)int.Parse(dic[propertyInfo.Name]));
					}
					else if (propertyInfo.Name == "PipeMaterial")
					{
						propertyInfo.SetValue(floorPipeGroupData.drawFloorPipeData, dic[propertyInfo.Name]);
					}
					else if (propertyInfo.Name == "BDrawCenter")
					{
						propertyInfo.SetValue(floorPipeGroupData.drawFloorPipeData, bool.Parse(dic[propertyInfo.Name]));
					}
					else
					{
						propertyInfo.SetValue(floorPipeGroupData.drawFloorPipeData, double.Parse(dic[propertyInfo.Name]));
					}
				}
			}
			else
			{
				if (floorPipeGroupData.drawYxFloorPipeData == null)
				{
					floorPipeGroupData.drawYxFloorPipeData = new DrawYxFloorPipeData();
				}
				foreach (PropertyInfo propertyInfo2 in floorPipeGroupData.drawYxFloorPipeData.GetType().GetProperties())
				{
					if (propertyInfo2.Name == "InType" || propertyInfo2.Name == "OutType")
					{
						propertyInfo2.SetValue(floorPipeGroupData.drawYxFloorPipeData, this.GetGraphicsStyleByName(dic[propertyInfo2.Name]));
					}
					else if (propertyInfo2.Name == "IsDouble")
					{
						propertyInfo2.SetValue(floorPipeGroupData.drawYxFloorPipeData, int.Parse(dic[propertyInfo2.Name]));
					}
					else if (propertyInfo2.Name == "PipeMaterial")
					{
						propertyInfo2.SetValue(floorPipeGroupData.drawYxFloorPipeData, dic[propertyInfo2.Name]);
					}
					else
					{
						propertyInfo2.SetValue(floorPipeGroupData.drawYxFloorPipeData, double.Parse(dic[propertyInfo2.Name]));
					}
				}
			}
			floorPipeGroupData.PipesLength = double.Parse(dic["PipeLength"]);
			floorPipeGroupData.PipeInId = new ElementId(int.Parse(dic["PipeInId"]));
			floorPipeGroupData.PipeLastId = ((dic["PipeLastId"] == "-1") ? null : new ElementId(int.Parse(dic["PipeLastId"])));
			return floorPipeGroupData;
		}

		public void SetElementES(Element group, FloorPipeGroupData fpgd)
		{
			IDictionary<string, string> dicFromFloorPipeGroupData = this.GetDicFromFloorPipeGroupData(fpgd);
			Schema schema = Schema.Lookup(new Guid("950B5E6F-E316-4B99-A808-750ACE02F4E8"));
			if (schema == null)
			{
				SchemaBuilder schemaBuilder = new SchemaBuilder(new Guid("950B5E6F-E316-4B99-A808-750ACE02F4E8"));
				schemaBuilder.SetReadAccessLevel((AccessLevel)1);
				schemaBuilder.SetWriteAccessLevel((AccessLevel)1);
				schemaBuilder.SetVendorId("ADSK");
				schemaBuilder.AddMapField("florPipeInfo", typeof(string), typeof(string));
				schemaBuilder.SetSchemaName("FloorPipeInfos");
				schema = schemaBuilder.Finish();
			}
			Entity entity = new Entity(schema);
			Field field = schema.GetField("florPipeInfo");
			entity.Set<IDictionary<string, string>>(field, dicFromFloorPipeGroupData);
			group.SetEntity(entity);
		}

		public FloorPipeGroupData GetElementES(Element group)
		{
			Schema schema = Schema.Lookup(new Guid("950B5E6F-E316-4B99-A808-750ACE02F4E8"));
			if (schema == null)
			{
				SchemaBuilder schemaBuilder = new SchemaBuilder(new Guid("950B5E6F-E316-4B99-A808-750ACE02F4E8"));
				schemaBuilder.SetReadAccessLevel((AccessLevel)1);
				schemaBuilder.SetWriteAccessLevel((AccessLevel)1);
				schemaBuilder.SetVendorId("ADSK");
				schemaBuilder.AddMapField("florPipeInfo", typeof(string), typeof(string));
				schemaBuilder.SetSchemaName("FloorPipeInfos");
				schema = schemaBuilder.Finish();
			}
			Entity entity = group.GetEntity(schema);
			if (!entity.IsValid())
			{
				return null;
			}
			IDictionary<string, string> dic = entity.Get<IDictionary<string, string>>(schema.GetField("florPipeInfo"));
			return this.GetFloorPipeDataFromDic(dic);
		}

		public double GetFloorPipeDistance(FloorPipeGroupData fpgd)
		{
			return Math.Round(((fpgd.drawFloorPipeData == null) ? fpgd.drawYxFloorPipeData.Dis : fpgd.drawFloorPipeData.MaxDistance()) * 304.8, 2);
		}

		public List<Element> CreatModelLine(List<XYZ> points)
		{
			List<Element> list = new List<Element>();
			for (int i = 1; i < points.Count; i++)
			{
				Element element = this.CreatModelLine(Line.CreateBound(points[i - 1], points[i]), null);
				if (element != null)
				{
					list.Add(element);
				}
				if (i == points.Count - 1)
				{
					element = this.CreatModelLine(Line.CreateBound(points[i], points[0]), null);
					if (element != null)
					{
						list.Add(element);
					}
				}
			}
			return list;
		}

		public List<Element> CreatModelLine(List<Curve> curves, GraphicsStyle graphicsStyle, ref ElementId firstId)
		{
			List<Element> list = new List<Element>();
			if (curves == null || curves.Count == 0)
			{
				return list;
			}
			for (int i = 0; i < curves.Count; i++)
			{
				Element element = this.CreatModelLine(curves[i], graphicsStyle);
				if (element != null)
				{
					list.Add(element);
					if (i == 0)
					{
						firstId = element.Id;
					}
				}
			}
			return list;
		}

		public List<Element> CreatModelLine(List<Curve> curves, GraphicsStyle graphicsStyle)
		{
			List<Element> list = new List<Element>();
			if (curves == null || curves.Count == 0)
			{
				return list;
			}
			for (int i = 0; i < curves.Count; i++)
			{
				Element element = this.CreatModelLine(curves[i], graphicsStyle);
				if (element != null)
				{
					list.Add(element);
				}
			}
			return list;
		}

		private Element CreatModelLine(Curve curve, GraphicsStyle graphicsStyle = null)
		{
			ModelCurve modelCurve = this.doc.Create.NewModelCurve(curve, this.doc.ActiveView.SketchPlane);
			if (graphicsStyle != null)
			{
				modelCurve.LineStyle = graphicsStyle;
			}
			Element result = null;
			if (modelCurve is ModelArc)
			{
				result = (modelCurve as ModelArc);
			}
			else if (modelCurve is ModelLine)
			{
				result = (modelCurve as ModelLine);
			}
			return result;
		}

		public Curve Daoyuanjiaotwolines(ref Line line1, ref Line line2, double dRadius)
		{
			XYZ intersectionPoint = this.GetIntersectionPoint(line1, line2);
			XYZ xyz = (this.GetFarEndPointfromBasePiont(line1, intersectionPoint) - intersectionPoint).Normalize();
			XYZ xyz2 = (this.GetFarEndPointfromBasePiont(line2, intersectionPoint) - intersectionPoint).Normalize();
			double num = YJKRevitTools.GetTwoVectorAngle(xyz, xyz2, new XYZ(0.0, 0.0, 1.0));
			if (num > Math.PI)
			{
				num = Math.PI*2 - num;
			}
			double num2 = dRadius / Math.Tan(0.5 * num);
			XYZ xyz3 = intersectionPoint + xyz * num2;
			XYZ xyz4 = intersectionPoint + xyz2 * num2;
			line1 = Line.CreateBound(this.GetFarEndPointfromBasePiont(line1, intersectionPoint), xyz3);
			line2 = Line.CreateBound(this.GetFarEndPointfromBasePiont(line2, intersectionPoint), xyz4);
			XYZ vectorByHorizontal = this.GetVectorByHorizontal(xyz);
			XYZ vectorByHorizontal2 = this.GetVectorByHorizontal(xyz2);
			Line line3 = Line.CreateUnbound(xyz3, vectorByHorizontal);
			Line line4 = Line.CreateUnbound(xyz4, vectorByHorizontal2);
			XYZ intersectionPoint2 = this.GetIntersectionPoint(line3, line4, true);
			XYZ xyz5 = intersectionPoint2 + dRadius * (intersectionPoint - intersectionPoint2).Normalize();
			return Arc.Create(xyz3, xyz4, xyz5);
		}

		public XYZ GetFarEndPointfromBasePiont(Line line, XYZ ptBase)
		{
			double num = line.GetEndPoint(0).DistanceTo(ptBase);
			double num2 = line.GetEndPoint(1).DistanceTo(ptBase);
			if (num <= num2)
			{
				return line.GetEndPoint(1);
			}
			return line.GetEndPoint(0);
		}

		public XYZ GetIntersectionPoint(Line l1, Line l2)
		{
			XYZ result = new XYZ();
			result = null;
			Line line = Line.CreateBound(l1.GetEndPoint(0), l1.GetEndPoint(1));
			Line line2 = Line.CreateBound(l2.GetEndPoint(0), l2.GetEndPoint(1));
			if (line.IsBound)
			{
				line.MakeUnbound();
			}
			if (line2.IsBound)
			{
				line2.MakeUnbound();
			}
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			SetComparisonResult setComparisonResult = line.Intersect(line2, out intersectionResultArray);
			if (4 != (int)setComparisonResult && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
			{
				result = intersectionResultArray.get_Item(0).XYZPoint;
			}
			return result;
		}

		public XYZ GetIntersectionPoint(Line line1, Line line2, bool unbound)
		{
			XYZ result = new XYZ();
			result = null;
			if (line1.IsBound)
			{
				line1.MakeUnbound();
			}
			if (line2.IsBound)
			{
				line2.MakeUnbound();
			}
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			SetComparisonResult setComparisonResult = line1.Intersect(line2, out intersectionResultArray);
			if (4 != (int)setComparisonResult && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
			{
				result = intersectionResultArray.get_Item(0).XYZPoint;
			}
			return result;
		}

		public XYZ GetVectorByHorizontal(XYZ hVector)
		{
			new XYZ();
			return new XYZ(0.0, 0.0, 1.0).CrossProduct(hVector);
		}

		public List<GraphicsStyle> GetLineStyle()
		{
			List<GraphicsStyle> list = new List<GraphicsStyle>();
			foreach (Element element in new FilteredElementCollector(this.doc).OfClass(typeof(GraphicsStyle)).ToElements())
			{
				GraphicsStyle graphicsStyle = element as GraphicsStyle;
				if (graphicsStyle.GraphicsStyleCategory.Parent != null && graphicsStyle.GraphicsStyleCategory.Parent.Id.IntegerValue == -2000051)
				{
					CategoryNameMapIterator categoryNameMapIterator = graphicsStyle.GraphicsStyleCategory.Parent.SubCategories.ForwardIterator();
					categoryNameMapIterator.Reset();
					while (categoryNameMapIterator.MoveNext())
					{
						object obj = categoryNameMapIterator.Current;
						Category category = obj as Category;
						if (category != null && graphicsStyle.Name == category.Name)
						{
							list.Add(graphicsStyle);
						}
					}
				}
			}
			return list;
		}

		public GraphicsStyle GetGraphicsStyleByName(string name)
		{
			return this.GetLineStyle().FirstOrDefault((GraphicsStyle item) => name == item.Name);
		}

		public IList<Element> ChamferModelLines(IList<ModelLine> modelLines, double dRadius)
		{
			List<MixPair> list = new List<MixPair>();
			foreach (ModelLine ml in modelLines)
			{
				list.Add(this.CreateMixPairByML(ml));
			}
			this.ChangeMixPairVector(ref list);
			List<MixPair> list2 = this.MergeMixPairs(list);
			List<ArcPtPair> source = this.MakeArcConnect(list2, dRadius);
			List<Curve> list3 = new List<Curve>();
			list3.AddRange((from mp in list2
			select mp.CreateCurve()).ToList<Curve>());
			list3.AddRange((from arc in source
			select arc.CreateArc()).ToList<Arc>());
			return this.CreatModelLine(list3, modelLines[0].LineStyle as GraphicsStyle);
		}

		private void ChangeMixPairVector(ref List<MixPair> mps)
		{
			if (mps.Count < 2)
			{
				return;
			}
			for (int i = 1; i < mps.Count; i++)
			{
				if (mps[i - 1].End.DistanceTo(mps[i].Start) > 0.0001 && mps[i - 1].Start.DistanceTo(mps[i].End) > 0.0001)
				{
					mps[i].DoExchange();
				}
			}
			if (mps[0].End.DistanceTo(mps[1].Start) > 0.0001)
			{
				mps.ForEach(delegate(MixPair mp)
				{
					mp.DoExchange();
				});
			}
		}

		private MixPair CreateMixPairByML(ModelLine ml)
		{
			XYZ endPoint = (ml.Location as LocationCurve).Curve.GetEndPoint(0);
			XYZ endPoint2 = (ml.Location as LocationCurve).Curve.GetEndPoint(1);
			return new MixPair(endPoint, endPoint2, false);
		}

		public List<ArcPtPair> MakeArcConnect(List<MixPair> mps, double dRad)
		{
			List<ArcPtPair> list = new List<ArcPtPair>();
			if (mps.Count < 3)
			{
				for (int i = 1; i < mps.Count; i++)
				{
					ArcPtPair arcPtPair = this.MakeArcConnect(mps[i - 1], mps[i], dRad);
					if (arcPtPair != null)
					{
						list.Add(arcPtPair);
					}
				}
			}
			else
			{
				double num = dRad;
				for (int j = 2; j < mps.Count; j++)
				{
					double num2 = dRad;
					if (mps[j - 2].IsParallel(mps[j]))
					{
						double num3 = mps[j - 2].DistanceTo(mps[j]);
						num2 = ((0.5 * num3 > num2) ? num2 : (0.5 * num3 - 0.0032808398950131233));
						if (num < num2)
						{
							num2 = num;
						}
						else
						{
							num = num2;
						}
					}
					ArcPtPair arcPtPair2 = this.MakeArcConnect(mps[j - 2], mps[j - 1], num2);
					if (arcPtPair2 != null)
					{
						list.Add(arcPtPair2);
					}
					if (j == mps.Count - 1)
					{
						arcPtPair2 = this.MakeArcConnect(mps[j - 1], mps[j], num2);
						if (arcPtPair2 != null)
						{
							list.Add(arcPtPair2);
						}
					}
				}
			}
			return list;
		}

		private ArcPtPair MakeArcConnect(MixPair mp1, MixPair mp2, double dMPDis = 0.0)
		{
			ArcPtPair arcPtPair = null;
			if (mp1.IsArc || mp2.IsArc)
			{
				return null;
			}
			Curve c = mp1.CreateCurve();
			Curve c2 = mp2.CreateCurve();
			XYZ intersectionPoint = this.GetIntersectionPoint(c, c2);
			if (intersectionPoint == null || mp1.AsVector().IsAlmostEqualTo(mp2.AsVector()))
			{
				return arcPtPair;
			}
			mp1.End = intersectionPoint;
			mp2.Start = intersectionPoint;
			if (dMPDis > 0.0 && !mp1.IsArc && !mp2.IsArc)
			{
				arcPtPair = new ArcPtPair();
				PointPair ppF = new PointPair(mp1.Start, mp1.End, mp1.IsIn, false);
				PointPair ppS = new PointPair(mp2.Start, mp2.End, mp2.IsIn, false);
				arcPtPair.ReInitByTwoPerPair(ppF, ppS, dMPDis, false);
				mp1.End = arcPtPair.Start;
				mp2.Start = arcPtPair.End;
			}
			return arcPtPair;
		}

		public List<MixPair> MergeMixPairs(List<MixPair> mps)
		{
			List<MixPair> list = new List<MixPair>();
			XYZ pts = mps[0].Start;
			for (int i = 1; i < mps.Count; i++)
			{
				if (!mps[i].IsIn.Equals(mps[i - 1].IsIn) || !mps[i].IsCollinearWith(mps[i - 1]))
				{
					if (mps[i - 1].IsArc)
					{
						list.Add(new MixPair(pts, mps[i - 1].Mid, mps[i - 1].End, mps[i - 1].IsIn));
					}
					else
					{
						list.Add(new MixPair(pts, mps[i - 1].End, mps[i - 1].IsIn));
					}
					pts = mps[i - 1].End;
				}
				if (i == mps.Count - 1)
				{
					if (mps[i - 1].IsArc)
					{
						list.Add(new MixPair(pts, mps[i].Mid, mps[i].End, mps[i].IsIn));
					}
					else
					{
						list.Add(new MixPair(pts, mps[i].End, mps[i].IsIn));
					}
				}
			}
			return list;
		}

		private XYZ GetIntersectionPoint(Curve c1, Curve c2)
		{
			List<XYZ> list = new List<XYZ>();
			XYZ endPoint = c1.GetEndPoint(1);
			XYZ endPoint2 = c2.GetEndPoint(0);
			if (c1.IsBound)
			{
				c1.MakeUnbound();
			}
			if (c2.IsBound)
			{
				c2.MakeUnbound();
			}
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			SetComparisonResult setComparisonResult = c1.Intersect(c2, out intersectionResultArray);
			if (4 != (int)setComparisonResult && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
			{
				for (int i = 0; i < intersectionResultArray.Size; i++)
				{
					list.Add(intersectionResultArray.get_Item(i).XYZPoint);
				}
			}
			if (list.Count == 0)
			{
				return null;
			}
			double num = list[0].DistanceTo(endPoint) + list[0].DistanceTo(endPoint2);
			XYZ result = list[0];
			foreach (XYZ xyz in list)
			{
				if (num > xyz.DistanceTo(endPoint) + xyz.DistanceTo(endPoint2))
				{
					num = xyz.DistanceTo(endPoint) + xyz.DistanceTo(endPoint2);
					result = xyz;
				}
			}
			return result;
		}

		private UIApplication uiApplication;

		private Document doc;
	}
}
